package controller;

import controller.listeners.MyRelationListSelectionListener;
import exceptions.RelationAlreadyInSetException;
import exceptions.RelationNotInSetException;
import exceptions.TransactionAlreadyInSetException;
import gui.NeptuneWindow;
import gui.dialogs.dbspec.DatabaseSpecDialog;
import modeller.databasedesignmodel.Attribute;
import modeller.databasedesignmodel.DatabaseDesign;
import modeller.databasedesignmodel.relation.Relation;
import modeller.databasedesignmodel.transaction.Transaction;
import modeller.databasedesignmodel.query.SequentialScanQuery;
import queped.SerializablePair;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashSet;

/**
 * Created by: Jason Ye
 * Date: 22/01/2012
 * Time: 15:57
 * The main interface for the controller module
 */
public class Controller {

    private final NeptuneWindow theWindow;

    private MyRelationListSelectionListener myRelationListSelectionListener;
    private ActionListener removeRelationButtonListener;
    private ActionListener addRelationButtonListener;
    private ActionListener renameRelationButtonListener;
    private ActionListener specDBButtonListener;
    private ActionListener evaluateButtonListener;

    public Controller(NeptuneWindow theWindow) {

        this.theWindow = theWindow;

        myRelationListSelectionListener = new MyRelationListSelectionListener();

        removeRelationButtonListener = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                System.out.println("Remove relation button pressed");

                removeRelationPressed();
            }
        };

        addRelationButtonListener = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                System.out.println("Add relation button pressed");

                addRelationPressed();
            }
        };


        renameRelationButtonListener = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                System.out.println("Rename relation button pressed");

                renameRelationPressed();
            }
        };

        specDBButtonListener = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                specDBButtonPressed();
            }
        };

        evaluateButtonListener = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {

                evaluateButtonPressed();


            }
        };

       // queueingNetworkGenerator = new QueueingNetworkGenerator();
    }

    /*
   debug
    */
    private void evaluateButtonPressed() {

        // create heap relation
        Relation relation = new Relation(2, 2, 2, 2);
        relation.setRelationName("yay");

        // create transaction with a single scan query (only one transaction class)
        SequentialScanQuery query = new SequentialScanQuery(new SerializablePair<Relation, HashSet<Attribute>>(relation,new HashSet<Attribute>()));
        Transaction transaction = new Transaction(1);
       // transaction.addQuery(query);

        // generate xml for queueing network
        DatabaseDesign dbDesign = new DatabaseDesign();

        //add relations and transactions
        try {

            dbDesign.addRelation(relation);
            dbDesign.addTransaction(transaction);

        } catch (RelationAlreadyInSetException e) {
            e.printStackTrace();
        } catch (TransactionAlreadyInSetException e) {
            e.printStackTrace();
        }

       // queueingNetworkGenerator.generateNetwork(dbDesign);

    }

    /*
   debug
    */

    private void specDBButtonPressed() {

        DatabaseSpecDialog specDialog = new DatabaseSpecDialog(theWindow, true);

    }

    private void renameRelationPressed() {

        String oldName = theWindow.getCurrentlySelectedRelation();

        // display dialog to prompt user into specifying new name
        String s = JOptionPane.showInputDialog(theWindow,
                "Please enter the new name for the Relation '" + oldName + "':",
                "Rename Relation",
                JOptionPane.PLAIN_MESSAGE
        );

        System.out.println("Relation " + oldName + " to rename to " + s);

        // null => cancel pressed; "" => nothing typed in textfield
        if (null != s && !s.equals("")) {
            // attempt to add the relation
            try {
                theWindow.renameRelation(oldName, s);
            } catch (RelationNotInSetException e) {
                JOptionPane.showMessageDialog(theWindow,
                        "Relation " + s + " doesn't exist!",
                        "Warning",
                        JOptionPane.WARNING_MESSAGE);
                e.printStackTrace();
            } catch (RelationAlreadyInSetException e) {

                JOptionPane.showMessageDialog(theWindow,
                        "New Relation name " + s + " already exists!",
                        "Warning",
                        JOptionPane.WARNING_MESSAGE);

                e.printStackTrace();
            }

            theWindow.setSelectedRelation(s);
        }
    }

    private void addRelationPressed() {
        String s = "";

        s = JOptionPane.showInputDialog(theWindow,
                "Please enter a name for the new Relation:",
                "New Relation",
                JOptionPane.PLAIN_MESSAGE
        );

        System.out.println(s + " to add");

        if (null != s && !s.equals("")) {
            // attempt to add the relation
            try {
                theWindow.addRelation(s);
            } catch (RelationAlreadyInSetException e) {
                JOptionPane.showMessageDialog(theWindow,
                        "Relation " + s + " already exists!",
                        "Warning",
                        JOptionPane.WARNING_MESSAGE);
            }
        }
    }

    public void initialise() {
        //add listeners
        addRelationSelectionListeners();
        addDBSpecificationButtonListener();
        addEvaluateButtonListener();

        theWindow.setVisible(true);
    }

    private void removeRelationPressed() {
        theWindow.removeRelation();
    }

    private void addRelationSelectionListeners() {

        theWindow.addRelationSelectionListeners(myRelationListSelectionListener);
        theWindow.addAddRelationButtonListener(addRelationButtonListener);
        theWindow.addRenameButtonListener(renameRelationButtonListener);
        theWindow.addRemoveRelationButtonListener(removeRelationButtonListener);

    }

    private void addDBSpecificationButtonListener() {

        theWindow.addDBSpecButtonListener(specDBButtonListener);
    }

    private void addEvaluateButtonListener() {
        theWindow.addEvaluateButtonListener(evaluateButtonListener);
    }

}
